@file:OptIn(ExperimentalMaterial3Api::class)

package com.kira.solo.schedule.edit

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.Divider
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerState
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberDrawerState
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
import androidx.hilt.navigation.compose.hiltViewModel
import com.kira.solo.schedule.R
import com.kira.solo.schedule.list.CaseLayout
import com.kira.solo.schedule.list.CaseListUiState
import com.kira.solo.schedule.pojo.CaseEditUiState
import com.kira.solo.schedule.pojo.PeriodType
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale

/**
 *
 * @packageName com.kira.solo.schedule.add
 * @date 2024/1/24 13:57
 * @author zhanglei
 */
@Composable
fun ScheduleEditTask(
    viewModel: ScheduleEditViewModel = hiltViewModel(),
    onBack: () -> Unit,
) {
    val uiState by viewModel.editUiState.collectAsState()
    val cases by viewModel.allCases.collectAsState(initial = CaseListUiState.INIT)
    ScheduleEditTask(
        uiState = uiState,
        casesUiState = cases,
        onTimeChanged = viewModel::onTimeChanged,
        onPeriodChanged = viewModel::onPeriodChanged,
        onDone = {
            if (viewModel.onDone()) {
                onBack()
            }
        },
        onBack = onBack,
        onSelectedIds = viewModel::onSelectCases
    )

}

@Composable
fun ScheduleEditTask(
    uiState: CaseEditUiState,
    casesUiState: CaseListUiState,
    onTimeChanged: (Int, Int) -> Unit,
    onPeriodChanged: (PeriodType) -> Unit,
    onDone: () -> Unit,
    onBack: () -> Unit,
    onSelectedIds: (List<Long>) -> Unit,
) {
    val timerState = rememberTimePickerState(
        initialHour = uiState.taskInfo.time.hour,
        initialMinute = uiState.taskInfo.time.minute,
        is24Hour = true
    )
    val scope = rememberCoroutineScope()
    LaunchedEffect(key1 = timerState.hour, key2 = timerState.minute) {
        if (timerState.hour != uiState.taskInfo.time.hour ||
            timerState.minute != uiState.taskInfo.time.minute
        ) {
            onTimeChanged(timerState.hour, timerState.minute)
        }
    }
    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    ModalNavigationDrawer(
        drawerState = drawerState,
        drawerContent = {
            Column {
                Button(onClick = { scope.launch { drawerState.close() } }) {
                    Text(text = "关闭", fontSize = 20.sp, color = Color.Blue)
                }

                BottomSheetCasesContent(
                    uiState = casesUiState,
                    selectedIds = uiState.taskInfo.caseIds,
                    onSelectedIds = onSelectedIds
                )
            }
        },
    ) {
        Scaffold(
            topBar = {
                TopAppBar(onBack) { onDone() }
            }) {
            Column(
                modifier = Modifier
                    .padding(it)
                    .verticalScroll(rememberScrollState())
                    .fillMaxSize()
            ) {
                Spacer(modifier = Modifier.height(15.dp))
                TimeLayout(timerState)
                Divider()

                ExecutePeriodLayout(uiState.taskInfo.periodType, onPeriodChanged)
                Divider()

                SelectCasesLayout {
                    scope.launch { drawerState.open() }
                }

                SelectedCases(uiState.uiState)
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopAppBar(onBack: () -> Unit, onDone: () -> Unit) {
    CenterAlignedTopAppBar(
        colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
            containerColor = colorResource(
                id = R.color.colorPrimary
            ),
            navigationIconContentColor = Color.Transparent,
            actionIconContentColor = Color.Transparent,
        ),
        title = {
            Text(
                text = "新增任务",
                color = Color.White
            )
        },
        navigationIcon = {
            Button(
                onClick = onBack,
                colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent)
            ) {
                Image(
                    painter = painterResource(id = R.drawable.head_icon_back),
                    contentDescription = "返回"
                )
            }
        },
        actions = {
            Button(
                onClick = onDone,
                colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent)
            ) {
                Text(text = "完成")
            }
        })
}

/**
 * 时间组件
 */
@Composable
fun TimeLayout(state: TimePickerState = rememberTimePickerState()) {
    val formatter = remember { SimpleDateFormat("hh:mm a", Locale.getDefault()) }
    val time by remember(state) {
        derivedStateOf {
            val cal = Calendar.getInstance()
            cal.set(Calendar.HOUR_OF_DAY, state.hour)
            cal.set(Calendar.MINUTE, state.minute)
            cal.isLenient = false
            formatter.format(cal.time)
        }
    }
    Box(propagateMinConstraints = false, modifier = Modifier.fillMaxWidth()) {
        Column {
            TimePicker(state = state, modifier = Modifier.fillMaxWidth())
            Spacer(
                modifier = Modifier
                    .height(15.dp)
                    .fillMaxWidth()
            )
            Box(
                modifier = Modifier
                    .padding(horizontal = 10.dp)
                    .height(50.dp)
                    .fillMaxWidth()
            ) {
                Text(
                    text = "执行时间",
                    fontSize = 18.sp,
                    color = Color.DarkGray,
                    modifier = Modifier.align(
                        Alignment.CenterStart
                    )
                )
                Text(
                    text = time, fontSize = 18.sp, color = Color.DarkGray,
                    modifier = Modifier.align(
                        Alignment.CenterEnd
                    )
                )
            }
        }
    }
}

/**
 * 触发周期组件
 */
@Composable
fun ExecutePeriodLayout(
    periodType: PeriodType,
    onChangePeriod: (PeriodType) -> Unit,
) {
    var popup by remember {
        mutableStateOf(false)
    }

    Box(
        Modifier
            .padding(horizontal = 10.dp)
            .fillMaxWidth()
            .height(50.dp)
            .clickable { popup = true }) {
        Text(
            text = "执行周期",
            fontSize = 18.sp,
            color = Color.Black,
            modifier = Modifier.align(Alignment.CenterStart)
        )

        Row(modifier = Modifier.align(Alignment.CenterEnd)) {
            Text(
                text = periodType.display,
                fontSize = 16.sp,
                color = Color.DarkGray,
                modifier = Modifier.align(Alignment.CenterVertically)
            )

            Image(
                painter = painterResource(id = R.drawable.dialog_action_drawable_scroll_left),
                contentDescription = "",
                alignment = Alignment.CenterEnd
            )
        }

        if (popup) {
            PeriodPopup(
                onDismissRequest = { popup = false },
                onChangePeriod = onChangePeriod
            )
        }


    }


}

/**
 * 触发周期弹框
 */
@Composable
fun PeriodPopup(
    onDismissRequest: () -> Unit,
    onChangePeriod: (PeriodType) -> Unit,
) {
    Popup(
        alignment = Alignment.BottomCenter,
        onDismissRequest = onDismissRequest,
        properties = PopupProperties(focusable = true)
    ) {
        LazyColumn(
            Modifier
                .background(Color.LightGray)
                .fillMaxWidth()
        ) {
            items(PeriodType.allType) {
                Box(
                    Modifier
                        .height(45.dp)
                        .fillMaxWidth()
                        .clickable {
                            onChangePeriod(it)
                            onDismissRequest()
                        }) {
                    Text(
                        text = it.display,
                        Modifier.align(Alignment.Center),
                        fontSize = 18.sp,
                        color = Color.Black
                    )
                    Divider(Modifier.align(Alignment.BottomCenter))
                }
            }
        }
    }
}

@Composable
fun SelectCasesLayout(showCasesSelector: () -> Unit) {

    Box(
        Modifier
            .padding(horizontal = 10.dp)
            .fillMaxWidth()
            .height(50.dp)
            .clickable { showCasesSelector() }) {
        Text(
            text = "选择用例",
            fontSize = 18.sp,
            color = Color.Black,
            modifier = Modifier.align(Alignment.CenterStart)
        )

        Row(modifier = Modifier.align(Alignment.CenterEnd)) {
            Text(
                text = "滑动选择执行任务",
                fontSize = 16.sp,
                color = Color.DarkGray,
                modifier = Modifier.align(Alignment.CenterVertically)
            )
            Image(
                painter = painterResource(id = R.drawable.dialog_action_drawable_scroll_left),
                contentDescription = "",
                alignment = Alignment.CenterEnd
            )
        }
    }


}

/**
 * 用例选择器弹框
 */
@Composable
fun BottomSheetCasesContent(
    uiState: CaseListUiState,
    selectedIds: List<Long>,
    onSelectedIds: (List<Long>) -> Unit,
) {
    var selectIds by remember(selectedIds) {
        mutableStateOf(selectedIds)
    }
    LaunchedEffect(key1 = selectIds) {
        onSelectedIds(selectIds)
    }
    Column {
        Box(
            Modifier
                .fillMaxWidth()
                .padding(horizontal = 15.dp)
                .height(50.dp)
        ) {
            Text(
                text = "请选择需要定时执行的任务",
                fontSize = 18.sp,
                color = Color.Blue
            )
        }
        Column(
            Modifier
                .fillMaxWidth()
                .background(Color.LightGray)
        ) {
            uiState.cases.forEach {
                val selected = selectIds.contains(it.id)
                val click by rememberUpdatedState(newValue = {
                    selectIds = if (selected) {
                        selectIds - it.id
                    } else {
                        selectIds + it.id
                    }
                })
                FilterChip(
                    selected = selected,
                    onClick = click,
                    label = {
                        CaseLayout(uiState = it) {
                            click()
                        }
                    },
                    leadingIcon = {
                        if (selected) {
                            Icon(
                                imageVector = Icons.Filled.Done,
                                contentDescription = "Done icon",
                                modifier = Modifier.size(FilterChipDefaults.IconSize)
                            )
                        }
                    })
            }
        }
    }
}

/**
 * 选中的用例
 */
@Composable
fun SelectedCases(uiState: CaseListUiState) {
    Column(
        Modifier
            .fillMaxWidth()
            .background(Color.LightGray)
    ) {
        uiState.cases.forEach {
            CaseLayout(uiState = it) {

            }
        }
    }
}

@Preview
@Composable
fun ScheduleEditTaskPreview() {
    MaterialTheme {
        ScheduleEditTask(
            uiState = CaseEditUiState.INIT,
            casesUiState = CaseListUiState.INIT,
            onTimeChanged = { _, _ -> },
            onPeriodChanged = {},
            onDone = {},
            onBack = {},
            onSelectedIds = {}
        )
    }
}